import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 游戏地址爬取
 */
public class GameDownloadCrawl {
	private static String baseUrl = "https://ffyx.vip";
	private static String loginUrl = baseUrl + "/member/login.php?action=login&from=https://ffyx.vip/index.php";
	private static String searchUrl = baseUrl + "?type=search";
	private static String buyUrl = baseUrl + "/buy.php";
	private static String downloadUrl = baseUrl + "/member/unlogin.php";

	public static void main(String[] args) {
		crawlDownload("1580313824", "15803138248818", "Ai少女").forEach(gameDetail -> {
			System.out.println(gameDetail.getTitle());
			System.out.println(gameDetail.getUrl());
			System.out.println();
		});
	}

	// 由于购买间隔，现在只能一次爬取一个游戏地址
	public static List<GameDetail> crawlDownload(String email, String password, String keyword) {
		// 登录，获取cookie
		String cookie = getCookie(email, password);
		System.out.println(cookie);
		// 搜索，获取游戏标题和游戏ID
		List<GameDetail> gameDetails = gameSearch(cookie, keyword);
		if (gameDetails.size() > 0) {
			// 购买，获取游戏下载链接
			gameBuy(gameDetails.get(0), cookie);
			// 使用genkey获取游戏下载链接
			getDownload(gameDetails.get(0));
		}
		return gameDetails;
	}

	// 登录并获取cookie
	public static String getCookie(String email, String pwd) throws RuntimeException {
		try {
			Connection.Response response = Jsoup.connect(loginUrl)
					.data("M_email", email)
					.data("M_pwd", pwd)
					.method(Connection.Method.POST).execute();
			return response.cookie("PHPSESSID");
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("登录失败，" + e.getMessage());
		}
	}

	// 获取游戏ID
	public static List<GameDetail> gameSearch(String cookie, String keyword) throws RuntimeException {
		ArrayList<GameDetail> gameDetails = new ArrayList<>();
		try {
			Document document = Jsoup.connect(searchUrl)
					.cookie("PHPSESSID", cookie)
					.header("content-type", "application/x-www-form-urlencoded")
					.data("type", "product")
					.data("keyword", keyword)
					.post();

			Elements elements = document.select(".entry-title>a");
			elements.forEach(element -> {
				String title = element.attr("title");
				String href = element.attr("href");
				String id = href.substring(href.lastIndexOf("&id=") + 4);
				gameDetails.add(new GameDetail(id, title));
			});
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("游戏ID获取失败，" + e.getMessage());
		}
		return gameDetails;
	}

	// 游戏购买，获取genkey
	// 由于有购买间隔，一分钟只能购买一个，所以不能一次购买所有
	public static void gameBuy(GameDetail gameDetail, String cookie) throws RuntimeException {
		try {
			Document document = Jsoup.connect(buyUrl)
					.cookie("PHPSESSID", cookie)
					.data("type", "product")
					.data("type", "productinfo")
					.data("id", gameDetail.getId())
					.get();

			Pattern pattern = Pattern.compile("\\?genkey=(\\d+)&");
			Matcher matcher = pattern.matcher(document.toString());
			if (matcher.find()) {
				gameDetail.setGenkey(matcher.group(1));
			} else { //超过购买间隔
				pattern = Pattern.compile("alert\\('(.+)'\\);");
				matcher = pattern.matcher(document.toString());
				if (matcher.find())
					throw new RuntimeException("游戏购买失败，" + matcher.group(1));
				else
					throw new RuntimeException("游戏购买失败，" + document);
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("游戏购买失败，" + e.getMessage());
		}
	}

	public static void getDownload(GameDetail gameDetail) throws RuntimeException {
		if (gameDetail.getGenkey() == null) return;

		try {
			Document document = Jsoup.connect(downloadUrl)
					.data("genkey", gameDetail.getGenkey())
					.data("address", "0")
					.get();

			String url = document.select(".form-control").get(0).text();
			gameDetail.setUrl(url);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("游戏下载链接获取失败，" + e.getMessage());
		}
	}
}